package ks.client.lobby;

import javax.swing.JOptionPane;
import javax.swing.JFrame;
import javax.swing.WindowConstants;


import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import ks.client.UserContext;
import ks.client.ipc.Client;
import ks.client.processor.Processor;
import ks.framework.interfaces.IConnectionHandler;

/**
 * Primary KS client frontEnd that acts as the central hub for much of the
 * client-side behavior.
 * <p>
 * From the lobby you can always get the UserContext.
 * <p>
 * @author George Heineman
 */
public class Lobby extends JFrame implements IConnectionHandler {
	// keep eclipse happy
	private static final long serialVersionUID = 1L;

	// my GUI
	RoomGUI inner;

	/** User context for connection information. */
	UserContext context;

	/**
	 * Each lobby must have a context in which to operate.
	 */
	public Lobby(UserContext context) {
		this.context = context;
		
		// prepare 
		initialize();
		
		// pass context along to RoomGUI
		inner.context = context;
		
		inner.getUserField().setText(context.getUser());
		inner.getPasswordField().setText(context.getPassword());
	}

	/**
	 * Return the user context for this lobby.
	 */
	public UserContext getUserContext() {
		return context;
	}
	
	/**
	 * Initialize GUI elements of this component.
	 */
	private void initialize() {
		inner = new RoomGUI(this);
		setContentPane(inner);
		setTitle("Sample KS frontend");
		setSize(850, 750);

		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

		addWindowListener(new WindowAdapter() {

			@Override
			public void windowOpened(WindowEvent we) {
				if (inner.context == null) {
					System.err.println("Lobby must have a configured UserContext object.");
					setVisible (false);
					dispose();
				}
			}
			
			@Override
			public void windowClosing(WindowEvent we) {

				int selection = JOptionPane.showConfirmDialog(null,
						"Are you sure you want exit?", "Kombat Solitaire",
						JOptionPane.YES_NO_OPTION,
						JOptionPane.WARNING_MESSAGE);
				if( selection == JOptionPane.YES_OPTION ) {
					tryToDisconnect();
					setVisible(false);
					dispose();
				} else {
					inner.append("Thank goodness you came to your senses!");
				}
			}
		});
	}

	/**
	 * Respond to changes in our connected status
	 * 
	 * @param status
	 */
	public void connected(boolean status) {
		inner.getLobbyOutput().setEditable(status);

		// update connect
		if (status) {
			inner.getConnectButton().setText("Disconnect");
			
			// now that we are connected we can set up the processor
			// for all requests coming back from the server
			Client client = context.getClient();
			client.setProcessor(new Processor(this));
		} else {
			inner.getConnectButton().setText("Connect");
		}
	}

	/**
	 * Try to disconnect from remote server.
	 * <p>
	 * If client not yet connected (because client is null) then return true
	 * since that is ok.
	 */
	public boolean tryToDisconnect() {
		Client client = context.getClient();
		if (client == null) { return true; }
		
		if (!client.disconnect()) {
			return false;
		}

		inner.resetLogin();

		return true;
	}

	/** May need to expose inner GUI elements during testing. */
	public RoomGUI getRoom() {
		return inner;
	}

	/**
	 * Append string to RoomGUI output.
	 * 
	 * @param s
	 */
	public void append(String s) {
		inner.append(s);

	}

}
